package com.pan.kang.security;

import com.pan.kang.common.Request;
import com.pan.kang.common.jwt.JwtConstants;
import com.pan.kang.common.jwt.JwtUser;
import com.pan.kang.common.jwt.JwtUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;

@Aspect
@Component
public class AuthAspect {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Pointcut("@annotation(com.pan.kang.security.Authorization)")
    public void pointCut() {
    }


    @Around("pointCut() && @annotation(authorization)")
    public Object around(ProceedingJoinPoint point, Authorization authorization) throws Throwable {

        HttpServletRequest httpServletRequest = ((ServletRequestAttributes)
                Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();

        ServletRequestAttributes servletRequestAttributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        JwtUser jwtUser = JwtUtil.getJwtUser(servletRequestAttributes.getRequest().getHeader("Authorization"));
        if (jwtUser == null) {
            throw new RuntimeException("用户未登录！！！");
        }
        List<String> ignoreUrls = TokenAuthorFilter.ignoreUrl;

        String token = stringRedisTemplate.opsForValue().get(JwtConstants.JWT_TOKEN_KEY.concat(jwtUser.getUserId()));

        boolean isIgnore = PermissionMatcher.checkPermission(ignoreUrls, httpServletRequest.getServletPath());
        if (!isIgnore && (token == null || token.isEmpty())) {
            throw new RuntimeException("token 过期！！！");
        }

        if (authorization.value().equals(AuthType.AUTO_USER)) {
            Request request = (Request) point.getArgs()[0];
            request.setJwtUser(jwtUser);
        }
        return point.proceed();
    }
}
